from __future__ import print_function

# http://docs.pythonboto.org/en/latest/ref/s3.html

import boto
import utils
from boto.s3.connection import S3Connection
from boto.s3.key import Key
from boto.s3.bucket import Bucket
import pycurl
import json
import cStringIO
import string
import sqlite3
import hmac
import hashlib
from math import floor, fmod
from time import sleep, time
import logging

class S3:
	class ExceptionMissingS3Param:
		def __init__(self, value):
			self.value = value
		def __str__(self):
			return self.value

	_aws_id = None
	_aws_key = None
	_s3_bucket = None
	_s3_obj = None
	_s3_bucket_obj = None
	_s3_reduced_redundancy = False
	_s3_encrypt = False
	
	_xfer_lastTime = None
	_xfer_lastXmit = None
	_xfer_lastRecv = None

	

	def __init__(self, aws_id, aws_key, s3_bucket, s3_reduced_redundancy, s3_encrypt):
		self._aws_id = aws_id
		logging.debug("AWS_ID is ({})".format(self._aws_id))
		print("****** AWS_ID is ({})".format(self._aws_id))
		if self._aws_id is None:
			raise self.ExceptionMissingS3Param("aws_id")

		self._aws_key = aws_key
		if self._aws_key is None:
			raise ExceptionMissingS3Param("aws_id")

		self._s3_bucket = s3_bucket
		if self._s3_bucket is None:
			raise ExceptionMissingS3Param("s3_bucket")

		self._s3_reduced_redundancy = s3_reduced_redundancy
		self._s3_encrypt = s3_encrypt

		self._s3_obj = S3Connection(self._aws_id, self._aws_key)
		self._s3_bucket_obj = Bucket(self._s3_obj, self._s3_bucket)
	
	def _calcPercent(self, numerator, denominator, precision = 2):
		return round((float(numerator) / float(denominator,)) * 100, precision)

	def _printPercentComplete(self, bytesXmited, bytesToXmit):
		try:
			secsElapsed = float(time()) - float(self._xfer_lastTime)
			xmitDiff = float(bytesXmited) - float(self._xfer_lastXmit)
			bytesPerSec = xmitDiff / secsElapsed
			bytesLeft = bytesToXmit - bytesXmited
			secsLeft = bytesLeft / bytesPerSec
		except:
			bytesPerSec = float(0)
			secsLeft = float(0)

		self._xfer_lastXmit = float(bytesXmited)
		self._xfer_lastTime = float(time())
		
		print("{} / {} ({}%) ({}/s)            \r".format(utils.humanSize(bytesXmited), utils.humanSize(bytesToXmit), self._calcPercent(bytesXmited, bytesToXmit), utils.humanSize(bytesPerSec)), end='')

	def putFile(self, fp, keyName, sizeOfFile = None):
		s3Key = Key(self._s3_bucket_obj)
                s3Key.key = keyName
		md5 = s3Key.compute_md5(fp)
		maxCB = 10
		# display status at least every 20k
		if sizeOfFile is not None:
			maxCB = round(sizeOfFile / 20480)
		bytesXmit = s3Key.set_contents_from_file(fp, reduced_redundancy = self._s3_reduced_redundancy, encrypt_key = self._s3_encrypt, cb=self._printPercentComplete, num_cb = maxCB, md5 = md5)
		return ({"bytesXmit": bytesXmit, "etag": string.strip(s3Key.etag, '"'), "md5": md5[0]})

	def getURL(self, keyname, seconds = 300):
		s3Key = Key(self._s3_bucket_obj)
		s3Key.key = keyname
		disposition = 'attachment; filename="%s"' % keyname
		response_headers = {'response-content-disposition': disposition,}
		return s3Key.generate_url(seconds, response_headers = response_headers)
		

